package com.mirror.tk.security.shiro.realm;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import com.mirror.tk.security.api.SubjectInfo;
import com.mirror.tk.security.api.SubjectService;

public class SampleRealm extends AuthorizingRealm {

    private Logger logger = LogManager.getLogger();

    private SubjectService subjectService;

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清空指定用户的授权缓存
     * @param userName
     */
    public void clearCachedAuthorizationInfo(String userName){
        //TODO 单独删除有问题，不知道原因，统一全部清除
        /*Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if(cache!=null) {
            cache.remove(userName);
        }*/
        clearAllCachedAuthorizationInfo();
    }

    /**
     * 清空所有用户的授权缓存
     */
    public void clearAllCachedAuthorizationInfo(){
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if(cache!=null) {
            cache.clear();
        }
    }

    /**
     * 登陆认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        SubjectInfo subject = subjectService.getSubject(token.getUsername());
        if(subject==null){
            throw new AuthenticationException("username \""+token.getUsername()+"\" is not found user");
        }
        SimpleAuthenticationInfo saInfo = new SimpleAuthenticationInfo(token.getPrincipal(), subject.getPassword(), subject.getPwdSalt() != null ? ByteSource.Util.bytes(subject.getPwdSalt()) : null, getName());
        return saInfo;
    }

    /**
     * 用户授权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userName = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //授予角色
        info.addRoles(subjectService.listRole(userName));
        //授予权限
        info.addStringPermissions(subjectService.listPermission(userName));
        logger.debug("User Name:{}, authorization info Roles:{}, Permissions:{}",
                userName,
                info.getRoles().toString(),
                info.getStringPermissions().toString());
        return info;
    }

    public SubjectService getSubjectService() {
        return subjectService;
    }

    public void setSubjectService(SubjectService subjectService) {
        this.subjectService = subjectService;
    }
    
}
